/********************************************************************************
 * Copyright (c) 2019-2020 [Open Lowcode SAS](https://openlowcode.com/)
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0 .
 *
 * SPDX-License-Identifier: EPL-2.0
 ********************************************************************************/

package org.openlowcode.design.data.properties.basic;

import java.io.IOException;
import java.util.ArrayList;

import org.openlowcode.design.data.ChoiceValue;
import org.openlowcode.design.data.DataAccessMethod;
import org.openlowcode.design.data.DataObjectDefinition;
import org.openlowcode.design.data.MethodAdditionalProcessing;
import org.openlowcode.design.data.MethodArgument;
import org.openlowcode.design.data.Property;
import org.openlowcode.design.data.argument.LargeBinaryArgument;
import org.openlowcode.design.data.argument.ObjectArgument;
import org.openlowcode.design.generation.SourceGenerator;
import org.openlowcode.design.generation.StringFormatter;
import org.openlowcode.design.module.Module;

/**
 * This property adds a printout to the object. This is an autogenerated PDF.
 * 
 * @author <a href="https://openlowcode.com/" rel="nofollow">Open Lowcode
 *         SAS</a> *
 */
public class PrintOut
		extends
		Property<PrintOut> {

	private Lifecycle parentlifecycle;
	private String printouthelperclass;
	private String label;
	private ChoiceValue[] triggerstates;

	/**
	 * Creates a print-out property. Print-out will be generated when the object
	 * reaches a certain state
	 * 
	 * @param name          technical name of the printout (unique identifier for
	 *                      the print-out)
	 * @param label         label that will show as name of the print-out
	 * @param triggerstates states of the object for which the print-out is
	 *                      triggered (the print-out is generated as predefined
	 *                      states, typically during review of after the document is
	 *                      validated)
	 */
	public PrintOut(String name, String label, ChoiceValue[] triggerstates) {
		super(name, "PRINTOUT");
		this.label = label;
		this.triggerstates = triggerstates;
	}

	@Override
	public void controlAfterParentDefinition() {
		if (parent.getPropertyByName("FILECONTENT") == null)
			throw new RuntimeException(
					"Object " + parent.getName() + " has print-out property, but misses the Filecontent property.");
		DataAccessMethod generateprintout = new DataAccessMethod("GENERATEPRINTOUT", null, false);
		generateprintout.addInputArgument(new MethodArgument("OBJECT", new ObjectArgument("OBJECT", parent)));
		this.addDataAccessMethod(generateprintout);

		DataAccessMethod generatepreview = new DataAccessMethod("GENERATEPREVIEW",
				new LargeBinaryArgument("PRINTOUT", false), false);
		generatepreview.addInputArgument(new MethodArgument("OBJECT", new ObjectArgument("OBJECT", parent)));
		this.addDataAccessMethod(generatepreview);

		Property<?> lifecycle = parent.getPropertyByName("LIFECYCLE");
		if (lifecycle == null)
			throw new RuntimeException("Parent object " + parent.getName() + " has no lifecycle");
		parentlifecycle = (Lifecycle) lifecycle;
		MethodAdditionalProcessing statechangepostprocessing = new MethodAdditionalProcessing(false,
				parentlifecycle.getDataAccessMethod("CHANGESTATE"));
		this.addMethodAdditionalProcessing(statechangepostprocessing);

		printouthelperclass = StringFormatter.formatForJavaClass(parent.getName())
				+ StringFormatter.formatForJavaClass(this.getInstancename()) + "PrintoutGenerator";
		String lifecycleclass = StringFormatter.formatForJavaClass(parentlifecycle.getLifecycleHelper().getName())
				+ "ChoiceDefinition";
		if (triggerstates == null)
			throw new RuntimeException("Array of trigger states is null");
		if (triggerstates.length == 0)
			throw new RuntimeException("Array of trigger states has no element");
		String lifecyclelist = "";
		for (int i = 0; i < triggerstates.length; i++) {
			ChoiceValue thistriggerstate = triggerstates[i];
			if (i > 0)
				lifecyclelist += ",";
			if (!parentlifecycle.getTransitionChoiceCategory().hasChoiceValue(thistriggerstate))
				throw new RuntimeException("Choice Value " + thistriggerstate.getName()
						+ " does not exist in lifecycle of object " + parent.getName() + ".");
			lifecyclelist += lifecycleclass + ".getChoice"
					+ StringFormatter.formatForJavaClass(thistriggerstate.getName()) + "()\n";
		}
		this.setExtraAttributes(
				",\"" + label + "\", new " + printouthelperclass + "(), new ChoiceValue[]{" + lifecyclelist + "}");
		this.addChoiceCategoryHelper("LIFECYCLEHELPER", parentlifecycle.getLifecycleHelper());

	}

	@Override
	public String[] getPropertyInitMethod() {
		return new String[0];
	}

	@Override
	public String[] getPropertyExtractMethod() {
		return new String[0];
	}

	@Override
	public ArrayList<DataObjectDefinition> getExternalObjectDependence() {
		return null;
	}

	@Override
	public void setFinalSettings() {

	}

	@Override
	public String getJavaType() {
		return null;
	}

	@Override
	public void writeDependentClass(SourceGenerator sg, Module module) throws IOException {
		sg.wl("import org.openlowcode.server.data.properties.PrintOutGenerator;");
		sg.wl("import " + parent.getOwnermodule().getPath() + ".utility." + printouthelperclass + ";");
	}

	@Override
	public String[] getPropertyDeepCopyStatement() {

		return null;
	}
}
